package com.marktrace.util;

/**
 * Created by hdwang on 2019/1/17.
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 *  加密工具类
 */
public class AESUtil {
    private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);

    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final String IV_STRING = "dgQwPUdhNRysKwbL";  //使用CBC模式，需要一个向量iv，可增加加密算法的强度
    private static final String CBC_PASSWORD = "ZhyJGxdPjrLNdbfH"; //加密密码

    /**
     * AES 加密操作
     *
     * @param content 待加密内容
     * @return 加密数据
     */
    public static byte[] encrypt(String content) {
        try {
            //创建密码器
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

            //密码key(超过16字节即128bit的key，需要替换jre中的local_policy.jar和US_export_policy.jar，否则报错：Illegal key size)
            SecretKeySpec keySpec = new SecretKeySpec(CBC_PASSWORD.getBytes("utf-8"),KEY_ALGORITHM);

            //向量iv
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV_STRING.getBytes("utf-8"));

            //初始化为加密模式的密码器
            cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivParameterSpec);

            //加密
            byte[] byteContent = content.getBytes("utf-8");
            byte[] result = cipher.doFinal(byteContent);

            return result;
        } catch (Exception ex) {
            logger.error(ex.getMessage(),ex);
        }

        return null;
    }

    /**
     * AES 解密操作
     *
     * @param content 密文
     * @return 明文
     */
    public static String decrypt(byte[] content) {

        try {
            //创建密码器
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

            //密码key
            SecretKeySpec keySpec = new SecretKeySpec(CBC_PASSWORD.getBytes("utf-8"),KEY_ALGORITHM);

            //向量iv
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV_STRING.getBytes("utf-8"));

            //初始化为解密模式的密码器
            cipher.init(Cipher.DECRYPT_MODE,keySpec,ivParameterSpec);

            //执行操作
            byte[] result = cipher.doFinal(content);

            return new String(result,"utf-8");
        } catch (Exception ex) {
            logger.error(ex.getMessage(),ex);
        }

        return null;
    }


    /**
     * AES加密之后使用base64输出
     * @return
     */
    public static String outBase64(String str){
        byte[] aesString = encrypt(str);
        return Base64.getEncoder().encodeToString(aesString);
    }

    /**
     * 获取base64之后转成AES密文并解密
     * @param str
     * @return
     */
    public static String inBase64(String str){
        byte[] aesString = Base64.getDecoder().decode(replaceEnter(str));
        return decrypt(aesString);
    }

    /**
     * 去除base64字符串中的换行符
     * @param str
     * @return
     */
    public static String replaceEnter(String str){
        String reg ="[\n-\r]";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }

    public static void main(String[] args) {
        String param = "{" +
                "\"licensePlate\": \"437470B0034002D\"," +
                "\"plateColor\": \"黄\"," +
                "\"startTime\" : \"2019-05-13 17:40:43\"," +
                "\"endTime\": \"2019-05-13 17:45:43\"" +
                "}";
        String result = outBase64(param);
        System.out.println("加密:"+result.toString());

        String str1 = inBase64(result);
        System.out.println(str1);

        String testStr = "kBJ5K/Z11ZID5ZZM6MoVwl17ESaievRDjhSP6GTq7Zj1U2AN+od7u3mWr7JOxHnKHDP3ElStDDhx\n" +
                "ptcguQfZFJxwhlA60J1gI+b2DXZKWnCmFRuQk94IwA5lOGU/OUo8lpAgGylhFtTB3hRuyuZo6a2k\n" +
                "SFGQ55gDaq87PvsB2Vo=";
        System.out.println(testStr);
        testStr = testStr.replace("\r\n","");
        System.out.println(replaceEnter(testStr));

        String str2 = inBase64(testStr);
        System.out.println(str2);
    }

}